package com.module.base.utils;


import java.util.Timer;
import java.util.TimerTask;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.Future;
import java.util.concurrent.FutureTask;
import java.util.concurrent.LinkedBlockingDeque;
import java.util.concurrent.RejectedExecutionHandler;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

/**
 * Author: yanxuwen
 * Date: 2023/2/7
 * Desc: 线程队列管理
 */
public class ThreadPoolManager {

    private static final String TAG = ThreadPoolManager.class.getSimpleName();

    private static ThreadPoolManager instance;
    private static Object mLock = new Object();

    public static ThreadPoolManager getInstance() {
        if (instance == null) {
            synchronized (mLock) {
                if (instance == null) {
                    instance = new ThreadPoolManager(false);
                }
            }
        }
        return instance;
    }

    public static ThreadPoolManager getInstance(boolean full) {
        if (instance == null) {
            synchronized (mLock) {
                if (instance == null) {
                    instance = new ThreadPoolManager(full);
                }
            }
        }
        return instance;
    }

    /**
     * 线程池
     */
    private ThreadPoolExecutor threadPoolExecutor;
    /**
     * 请求队列
     */
    private LinkedBlockingDeque<Future<?>> service = new LinkedBlockingDeque<>();

    //线程池拒绝执行以后，放入阻塞队列
    private RejectedExecutionHandler handler = new RejectedExecutionHandler() {
        @Override
        public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {
            try {
                service.put(new FutureTask<Object>(r, null));
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    };

    /**
     * 初始化
     */
    private ThreadPoolManager(boolean full) {
        if (full) {
            //根据手机核心开启线程数量
            int size = Runtime.getRuntime().availableProcessors() * 2;
            threadPoolExecutor = new ThreadPoolExecutor(size, size,
                    0, TimeUnit.MILLISECONDS, new LinkedBlockingDeque<>(), handler);
        } else {
            threadPoolExecutor = new ThreadPoolExecutor(4, 10,
                    10, TimeUnit.SECONDS, new ArrayBlockingQueue<Runnable>(4), handler);
        }
        threadPoolExecutor.execute(runnable);

    }

    /**
     * 初始化
     */
    private ThreadPoolManager() {

    }

    /**
     * 消费者，不断检测线程队列是否有线程需要执行
     */
    private Runnable runnable = new Runnable() {
        @Override
        public void run() {
            while (true) {
                FutureTask futureTask = null;

                try {
//                    LogUtils.e("队列中等待数量：" + service.size());
                    futureTask = (FutureTask) service.take();
//                    LogUtils.e("线程池中线程的数量：" + threadPoolExecutor.getPoolSize());
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }

                if (futureTask != null) {
                    //消费需要执行的线程
                    threadPoolExecutor.execute(futureTask);
                }

            }
        }
    };

    public void execute(final Runnable runnable) {
        execute(new FutureTask<>(runnable, null), 0l);
    }

    /**
     * 执行线程任务，延时多少秒执行，相当于生产者，把需要执行的线程放入消息队列
     *
     * @param futureTask
     * @param delayed
     * @param <T>
     */
    public <T> void execute(final FutureTask<T> futureTask, Object delayed) {
        if (futureTask != null) {
            //延时执行
            if (delayed != null) {
                Timer timer = new Timer();
                timer.schedule(new TimerTask() {
                    @Override
                    public void run() {
                        try {
                            service.put(futureTask);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                }, (long) delayed);
            } else {
                //不需要延迟处理
                try {
                    service.put(futureTask);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }

}